﻿@model StackExchange.Opserver.Views.HAProxy.HAProxyModel
@{
    Layout = "HAProxy.cshtml";
    
    const int maxTopRoutesToShow = 10;
    IEnumerable<dynamic> sites = Model.Hosts.Select(s => new { host = s });
    var topRoutes = Model.TopRoutes;
}
<script>
    $(function () {
        function htmlEncode(s) {
            return document.createElement('div').appendChild(document.createTextNode(s)).parentNode.innerHTML;
        }
            
        function getHost(s) {
            s = s || '';
            return s.indexOf('api.') == 0 ? s.substr(4) : s;
        }

        $("#host").click(function () {
            $(this).select();  
        }).autocomplete(@Json.Encode(sites).AsHtml(), { 
            max: 100, 
            matchContains: true,
            delay: 100,
            formatItem: function (row) {
                    return '<img src="//' + getHost(row.host) + '/favicon.ico" width="16" height="16"/> ' + htmlEncode(row.host);
            },
            formatResult: function (row) { return htmlEncode(row.host); },
            formatMatch: function (row) { return row.host; }
        }).result(function (e, data) {
            $(this).css("background", 'url("//' + getHost(data.host) + '/favicon.ico") no-repeat')
                    .closest("form").submit();
        }).keydown(function(e) {
            return e.keyCode != 13;
        });
    });
</script>
@if (Model.Host.HasValue())
{
<style type="text/css">
    #host { background: url('//@Model.Host.Replace("api.","")/favicon.ico') 2px 2px no-repeat; background-size: 16px 16px; }
</style>
}
<div style="padding: 4px; width: 1200px; margin: 0 auto;">
    <h2>
        Stack Exchange Network Traffic
        <form method="GET" action="/haproxy/traffic" style="float: right;">
            <div>
                <input type="text" placeholder="All Sites" value="@Model.Host" id="host" name="host" />
            </div>
        </form>
    </h2>
    @{
        var start = DateTime.UtcNow.Date.AddMonths(-6).ToEpochTime(true);
        var end = DateTime.UtcNow.Date.AddDays(1).ToEpochTime(true);
        var subtitle = Model.Host.HasValue() ? "Traffic for " + Model.Host : "Global Network Traffic";
    }
    <div class="history-graph-wrap"><div id="hits-container" class="history-graph" style="height: 420px;"></div></div>
    <script>
        Status.Graphs.init({ start: @start, end: @end });
        $(function() {
            $('#hits-container').haproxyGraph({ title: 'HAProxy Traffic', subtitle: '@subtitle', params: { host: '@Model.Host' } });
            $('#content').on('click', '.route-row', function () {
                if ($('#route-graph').length) return;
                var route = $(this).data('route'),
                    days = $(this).data('days'),
                    host = $(this).data('host'),
                    container = '<div id="route-graph"><div class="cpu-total"><div id="route-time-graph" class="chart route-chart" data-title="Route Time Breakdown"></div></div></div>',
                    wrap = $(container).appendTo('#content');

                $('#route-time-graph').haproxyRouteGraph(route, days, host);

                wrap.modal({
                    overlayClose: true,
                    onClose: function (dialog) {
                        dialog.data.fadeOut('fast', function () {
                            dialog.container.hide('fast', function () {
                                $.modal.close();
                                $('#route-graph').remove();
                            });
                        });
                    }
                });
            });
        });
    </script>
</div>
<style>
    .route-row .node .value:after {
        content: ', '
    }
    .route-row .node .value:last-child:after {
        content: ''
    }
</style>

<div class="route-times">
    <h2 style="padding-bottom: 4px; overflow: auto;">Top Hit Routes <span class="note">(Last 30 Days)</span>
        @if (topRoutes.Count > 0)
        {
            <div class="legend chart route-chart">
                <div class="legend-item">
                    <div class="legend-block" style="background-color: #0E2A4C"></div> ASP.Net
                </div>
                <div class="legend-item">
                    <div class="legend-block" style="background-color: #143D65"></div> SQL
                </div>
                <div class="legend-item">
                    <div class="legend-block" style="background-color: #194D79"></div> Redis
                </div>
                <div class="legend-item">
                    <div class="legend-block" style="background-color: #1D5989"></div> HTTP
                </div>
                <div class="legend-item">
                    <div class="legend-block" style="background-color: #206396"></div> Tag Engine
                </div>
                <div class="legend-item">
                    <div class="legend-block" style="background-color: #64B6D0"></div> Other
                </div>
            </div>
        }
    </h2>
    @helper RouteTimePart(string label, decimal? ms)
    {
        if (ms.GetValueOrDefault() == 0) {return;}
        <span class="time">@label <span class="value">@string.Format("{0:n1}", ms)</span> ms</span>}
    <table>
        <thead>
            <tr>
                <th>Route</th>
                <th>Info</th>
                <th style="width: 306px;">Performance</th>
                <th style="width: 306px;">Hits</th>
            </tr>
        </thead>
        <tbody>
        @{
            var i = 0;
            if (topRoutes.Count == 0)
            {
                <tr>
                    <td colspan="4" style="text-align: center; padding: 20px 0;">No route info available for this host</td>
                </tr>   
            }        
            foreach (var r in topRoutes)
            {
                <tr class="route-row" data-route="@r.RouteName" data-days="30" data-host="@Model.Host">
                    <td class="route-name">@r.RouteName</td>
                    <td>
                        <div>
                            <table class="nvp">
                                <tr>
                                    <td class="name">Hits:</td>
                                    <td class="value">@string.Format("{0:n0}", @r.Hits)</td>
                                </tr>
                                <tr>
                                    <td class="name">Avg Total (Last 24):</td>
                                    <td class="value">@string.Format("{0:n0} ms", @r.AvgTr24Hrs)</td>
                                </tr>
                                <tr>
                                    <td class="name">Avg Breakdown (Last 24):</td>
                                    <td class="node">
                                        @r.AvgAspNetDurationMs24Hrs
                                        @r.AvgSqlDurationMs24Hrs
                                        @r.AvgRedisDurationMs24Hrs
                                        @r.AvgHttpDurationMs24Hrs
                                        @r.AvgTagEngineDurationMs24Hrs
                                        (@RouteTimePart("ASP.Net", r.AvgCalculatedAspNetDurationMs)@RouteTimePart("SQL", r.AvgSqlDurationMs24Hrs)@RouteTimePart("Redis", r.AvgRedisDurationMs24Hrs)@RouteTimePart("HTTP", r.AvgHttpCount24Hrs)@RouteTimePart("Tag Engine", r.AvgTagEngineDurationMs24Hrs)@RouteTimePart("Other", r.AvgCalculatedOtherDurationMs))
                                    </td>
                                </tr>
                                <tr>
                                    <td class="name">Avg SQL (Last 24):</td>
                                    <td class="value">@string.Format("{0:n0} ms", @r.AvgSqlDurationMs24Hrs)</td>
                                </tr>
                            </table>
                        </div>                
                    </td>
                    <td><img src="/graph/haproxy/route-performance?days=30&host=@Model.Host&route=@r.RouteName.UrlEncode()&alt=@(i % 2 == 0)" width="300" height="70" alt="Performance last 30 days"/></td>
                    <td><img src="/graph/haproxy/route-hits?days=30&host=@Model.Host&route=@r.RouteName.UrlEncode()&alt=@(i % 2 == 0)" width="300" height="70" alt="Hits last 30 days"/></td>
                </tr>
                if (i++ >= maxTopRoutesToShow) { break; }
            }
        }
        </tbody>
    </table>
</div>